package com.kellycheung.chicken_go_go;

import com.kellycheung.chicken_go_go.BaseObject.GOAnchor;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;

public class GRectangle extends GGeometry {
	protected float fUp;
	protected float fDown;
	protected float fLeft;
	protected float fRight;
	
	
	public GRectangle( GRectangle p_gr  ) {
		this( p_gr.fRight , p_gr.fUp , p_gr.fLeft , p_gr.fDown ); 
	}
	
	public GRectangle( GCoordinate p_gcUpLeft , GCoordinate p_gcDownRight ) {
		this( p_gcDownRight.fX , p_gcUpLeft.fY , p_gcUpLeft.fX , p_gcDownRight.fY ); 
	}
	
	public GRectangle( float p_fRight , float p_fUp , float p_fLeft , float p_fDown ) {
		try {
			this.set( p_fRight , p_fUp , p_fLeft , p_fDown );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GRectangle" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void set( GCoordinate p_gcUpLeft , GCoordinate p_gcDownRight ) {
		try {
			this.set( p_gcDownRight.fX , p_gcUpLeft.fY , p_gcUpLeft.fX , p_gcDownRight.fY );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GRectangle.set(GCoordinate,GCoordinate)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void set( GRectangle p_gr ) {
		try {
			this.set( p_gr.fRight , p_gr.fUp , p_gr.fLeft , p_gr.fDown );
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GRectangle.set(GRectangle)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public void set( float p_fRight , float p_fUp , float p_fLeft , float p_fDown ) {
		try {
			this.fUp = p_fUp;
			this.fDown = p_fDown;
			this.fLeft = p_fLeft;
			this.fRight = p_fRight;
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GRectangle.set(float,float,float,float)" );
			GameUtil.ErrorHandler( this , p_e );
		}
	}
	
	public boolean isInside( float p_fX , float p_fY ) {
		return this.isInside( new GCoordinate( p_fX , p_fY ) );
	}
	
	public boolean isInside( GCoordinate p_gc ) {
		try {
			if ( p_gc.fX < this.fLeft ) {
				return false;
			}
			else if ( p_gc.fX > this.fRight ) {
				return false;
			}
			else if ( p_gc.fY < this.fUp ) {
				return false;
			}
			else if ( p_gc.fY > this.fDown ) {
				return false;
			}
			else {
				return true;
			}
		} catch ( Exception p_e ) {
			// TODO Auto-generated catch block
			GameUtil.LogMsg( this , "GRectangle.isInside" );
			GameUtil.ErrorHandler( this , p_e );
		}
		
		return false;
	}
	
	public String toString() {
		return this.toString( false );
	}
	
	public String toString( boolean p_bRound ) {
		if ( p_bRound ) {
			return "(" + Integer.valueOf(Math.round(this.fLeft)) + "," + Integer.valueOf(Math.round(this.fUp)) + ":" + Integer.valueOf(Math.round(this.fRight)) + "," + Integer.valueOf(Math.round(this.fDown)) + ")";
		}
		else {
			return "(" + this.fLeft + "," + this.fUp + " : " + this.fRight + "," + this.fDown + ")";
		}
	}
	
	public Rect toRect() {
		return new Rect( Math.round(this.fLeft) , Math.round(this.fUp) , Math.round(this.fRight) , Math.round(this.fDown) );
	}
	
	public boolean isCollided( GRectangle p_gr ) {
		if ( this.isInside(p_gr.fLeft ,  p_gr.fUp ) ) {
			return true;
		}
		else if ( this.isInside( p_gr.fRight , p_gr.fUp ) ) {
			return true;
		}
		else if ( this.isInside( p_gr.fLeft , p_gr.fDown ) ) {
			return true;
		}
		else if ( this.isInside( p_gr.fRight , p_gr.fDown ) ) {
			return true;
		}
		
		return false;
	}
	
	public void setX( float p_fX ) {
		this.fRight = (this.fRight - this.fLeft) + p_fX;
		this.fLeft = p_fX;
	}

	public void setY( float p_fY ) {
		this.fDown = (this.fDown - this.fUp) + p_fY;
		this.fUp = p_fY;
	}
	
	public float getWidth() {
		return this.fRight - this.fLeft;
	}

	public float getHeight() {
		return this.fDown - this.fUp;
	}
	
	public GCoordinate getCenter() {
		return new GCoordinate( this.fLeft + this.getWidth()/2 , this.fUp + this.getHeight()/2 );
	}
	
	public GRectangle scale( float p_fXScale , float p_fYScale , GOAnchor p_goa ) {
		GRectangle grNew = new GRectangle( this );
		float fW = grNew.getWidth() * (1f-p_fXScale);
		float fH = grNew.getHeight() * (1f-p_fYScale);
		
		switch ( p_goa ) {
		case UpLeft:
		case Left:
		case DownLeft:
			grNew.fRight = grNew.fRight - fW; 
			break;
		case Up:
		case Center:
		case Down:
			grNew.fLeft = grNew.fLeft + fW/2f; 
			grNew.fRight = grNew.fRight - fW/2f; 
			break;
		case UpRight:
		case Right:
		case DownRight:
			grNew.fLeft = grNew.fLeft + fW;
			break;
		default:
			break;
		}
		
		switch ( p_goa ) {
		case UpLeft:
		case Up:
		case UpRight:
			grNew.fDown = grNew.fDown - fH; 
			break;
		case Left:
		case Center:
		case Right:
			grNew.fUp = grNew.fUp + fH/2f; 
			grNew.fDown = grNew.fDown - fH/2f; 
			break;
		case DownLeft:
		case Down:
		case DownRight:
			grNew.fUp = grNew.fUp + fH; 
			break;
		default:
			break;
		}
		
		return grNew;
	}

	@Override
	public void draw( Canvas p_c , Paint p_p , int p_iColor , int p_iAlpha ) {
		// TODO Auto-generated method stub
		Paint p = new Paint( p_p );
		
		p.setColor( p_iColor );
		p.setAlpha( p_iAlpha );
		
		p_c.drawRect( this.toRect() , p );
	}

	@Override
	public GRectangle convCoord( GOAnchor p_goa ) {
		// TODO Auto-generated method stub
		GRectangle grNew = new GRectangle( this );
		float fW = grNew.getWidth();
		float fH = grNew.getHeight();
		
		switch ( p_goa ) {
		case UpLeft:
		case Left:
		case DownLeft:
			grNew.fLeft = grNew.fLeft + fW/2f; 
			grNew.fRight = grNew.fRight + fW/2f; 
			break;
		case UpRight:
		case Right:
		case DownRight:
			grNew.fLeft = grNew.fLeft - fW/2f; 
			grNew.fRight = grNew.fRight - fW/2f; 
			break;
		default:
			break;
		}
		
		switch ( p_goa ) {
		case UpLeft:
		case Up:
		case UpRight:
			grNew.fUp = grNew.fUp + fH/2f; 
			grNew.fDown = grNew.fDown + fH/2f; 
			break;
		case DownLeft:
		case Down:
		case DownRight:
			grNew.fUp = grNew.fUp - fH/2f; 
			grNew.fDown = grNew.fDown - fH/2f; 
			break;
		default:
			break;
		}
		
		return grNew;
	}
}
